package com.copm.ifm.base.service.tree;

import cn.hutool.core.util.StrUtil;
import com.copm.ifm.base.basic.exception.ServiceException;
import com.google.common.base.Charsets;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.*;

/**
 * 树状结构工具类
 *
 * @author zzf
 * @date 2020/7/30 11:14
 */
public class TreeUtil {

    public static final int DEFAULT_PATH_LENGTH = 4;

    private static final DecimalFormat format = new DecimalFormat("0000");


    /**
     * 获得第一个子集的编号
     */
    public static String getFirstChildPath(String parentPath) {
        return (parentPath == null ? "" : parentPath) + format.format(1);
    }

    /**
     * 获得下一个子集的编号
     *
     * @param prevChildPath 上一个子集的编号
     */
    public static String getNextChildPath(String prevChildPath) {
        Number num;
        try {
            num = format.parse(prevChildPath.substring(prevChildPath.length() - DEFAULT_PATH_LENGTH));
        } catch (ParseException e) {
            throw new ServiceException("编码生成错误，请联系管理员~");
        }
        return getParentPath(prevChildPath) + format.format(num.intValue() + 1);
    }

    /**
     * 获得父路径
     */
    public static String getParentPath(String childPath) {
        int level = childPath.length() / DEFAULT_PATH_LENGTH;
        return childPath.substring(0, (level - 1) * DEFAULT_PATH_LENGTH);
    }

    /**
     * 根据路径获得层级
     */
    public static Integer getLevel(String path) {
        if (path == null) {
            return 0;
        }
        return path.length() / DEFAULT_PATH_LENGTH;
    }

    /**
     * 获取路径当层的序号
     */
    public static String getPathEnd(String path) {
        return path.substring(path.length() - DEFAULT_PATH_LENGTH);
    }

    /**
     * 获取指定path的所有父级path
     *
     * @param path 树状结构数据编码
     * @return 所有父级节点编码
     */
    public static List<String> getAllParentPath(String path) {
        if (StrUtil.isBlank(path)) {
            return new ArrayList<>();
        }
        byte[] bytes = path.getBytes(Charsets.UTF_8);

        if (bytes.length % 4 > 0) {
            throw new ServiceException("[getAllParentPath Error] valid path :" + path);
        }
        List<String> parentPaths = new ArrayList<>();

        for (int i = 1; i < getLevel(path); i++) {
            parentPaths.add(path.substring(0, path.length() - 4 * i));
        }
        return parentPaths;
    }

    /**
     * 获取指定所有path的所有父级path
     *
     * @param paths 树状结构数据编码path集合
     * @return 所有父级节点编码
     */
    public static Set<String> getAllParentPath(Collection<String> paths) {
        Set<String> result = new HashSet<>();
        paths.stream().map(TreeUtil::getAllParentPath).forEach(result::addAll);
        return result;
    }

}
